--- 'Nice' instance for 'ExprS'
module frege.compiler.instances.NiceExprS where

import Compiler.classes.Nice
import Compiler.instances.Nicer
import Compiler.types.Global
import Compiler.types.SourceDefinitions

instance Nice ExprS where
    nice :: ExprS -> Global -> String
    nice e g  = case e of
        Vbl{name} -> name.show   
        Lit{pos, kind, value} -> value
        Con{name} -> show name
        ConFS{name, fields} -> 
            show name ++ "{" 
                ++ joined ", " (map showfield fields) 
                ++ "}" 
                where
                    showfield (label, ex)  = label ++ "=" ++ nice ex g
        App{fun, arg} -> nice fun g ++ " " ++ nice arg g
        Let{defs, ex} -> "let ... in " ++ nice ex g
        Lam{pat, ex}  -> "\\" ++ nice pat g ++ " -> " ++ nice ex g
        Ifte{cnd, thn, els} -> "if " ++ nice cnd g ++ " then " ++ nice thn g ++ " else " ++ nice els g
        Mem{ex, member}     -> nice ex g ++ "." ++ member.value
        Case{ckind, ex, alts} -> "case " ++ nice ex g ++ " of {" ++ nicea alts ++ "}"
                where
                    nice1a CAlt{pat, ex} = "{" ++ nice pat g ++ " -> " ++ nice ex g ++ "}"
                    nicea [ca]   = nice1a ca
                    nicea (ca:_) = nice1a ca ++ ";..."
                    nicea []     = "???"   -- cannot happen
        Ann{ex, typ} -> nicer ex g ++ "::" ++ nicer typ g 
        Term{ex} -> "(" ++ nicer ex g ++ ")"
        Infx{name, left, right} -> nicer left g ++ show name ++ nicer right g
        Enclosed{ex} → nice ex g

    
